package com.cloudlead.common.worker.web;

import com.cloudlead.common.lang.api.ErrorActionResponse;
import com.cloudlead.common.lang.serialize.JSON;
import com.cloudlead.common.lang.utils.ExceptionHelper;
import com.cloudlead.common.worker.ApiService;
import com.sun.enterprise.ee.cms.core.GMSException;
import com.sun.enterprise.ee.cms.core.GroupManagementService;
import com.sun.enterprise.ee.cms.core.MessageSignal;
import com.sun.enterprise.ee.cms.impl.client.MessageActionFactoryImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.TimeoutHandler;
import javax.ws.rs.core.Response;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Created by dean on 2015/8/4.
 */
@Component
public class RemoteServiceRpcServer {
    private static final Logger LOGGER = LoggerFactory
            .getLogger(RemoteServiceRpcServer.class);
    @Autowired
    ApiService apiService;

    @PostConstruct
    public void start() {
        GroupManagementService gms = WorkerManager.getInstance().getGMS();
        gms.addActionFactory(new MessageActionFactoryImpl(notification -> {
            if (notification instanceof MessageSignal) {
                MessageSignal messageSignal = (MessageSignal) notification;
                String messageString = new String(messageSignal.getMessage());
                LOGGER.debug("==> server receive from [" + notification.getMemberToken() + "] request is :" + messageString);
                RemoteServiceRequest remoteServiceRequest = JSON.toBean(messageString, RemoteServiceRequest.class);
                AsyncResponse asyncResponse = new AsyncResponse() {
                    @Override
                    public boolean resume(Object response) {
                        try {
                            Response response1 = (Response) response;
                            String responseStr = JSON.toString(response1.getEntity());
                            LOGGER.debug("<== server send to [" + notification.getMemberToken() + "] response is :" + responseStr);
                            gms.getGroupHandle().sendMessage(notification.getMemberToken(), RemoteServiceRpcClient.RPC_RESPONSE_COMPONENT, responseStr.getBytes());
                        } catch (GMSException e) {
                            e.printStackTrace();
                            LOGGER.error("GMS send response message error.", e);
                        }
                        return false;
                    }

                    @Override
                    public boolean resume(Throwable response) {
                        return false;
                    }

                    @Override
                    public boolean cancel() {
                        return false;
                    }

                    @Override
                    public boolean cancel(int retryAfter) {
                        return false;
                    }

                    @Override
                    public boolean cancel(Date retryAfter) {
                        return false;
                    }

                    @Override
                    public boolean isSuspended() {
                        return false;
                    }

                    @Override
                    public boolean isCancelled() {
                        return false;
                    }

                    @Override
                    public boolean isDone() {
                        return false;
                    }

                    @Override
                    public boolean setTimeout(long time, TimeUnit unit) {
                        return false;
                    }

                    @Override
                    public void setTimeoutHandler(TimeoutHandler handler) {

                    }

                    @Override
                    public Collection<Class<?>> register(Class<?> callback) {
                        return null;
                    }

                    @Override
                    public Map<Class<?>, Collection<Class<?>>> register(Class<?> callback, Class<?>... callbacks) {
                        return null;
                    }

                    @Override
                    public Collection<Class<?>> register(Object callback) {
                        return null;
                    }

                    @Override
                    public Map<Class<?>, Collection<Class<?>>> register(Object callback, Object... callbacks) {
                        return null;
                    }
                };

                try {
                    Map<String, String> requestHeaders = new HashMap<>();
                    apiService.execute(remoteServiceRequest.getAction(), remoteServiceRequest.getActionRequest(), requestHeaders, asyncResponse);
                } catch (Exception e) {
                    e.printStackTrace();
                    LOGGER.error("Action execute error.", e);
                    ErrorActionResponse response = ExceptionHelper.toResponse(e);
                    try {
                        gms.getGroupHandle().sendMessage(notification.getMemberToken(), RemoteServiceRpcClient.RPC_RESPONSE_COMPONENT, JSON.toString(response).getBytes());
                    } catch (GMSException e1) {
                        e1.printStackTrace();
                        LOGGER.error("GMS send exception response message error.", e1);
                    }
                }
            }
        }), RemoteServiceRpcClient.RPC_REQUST_COMPONENT);
    }

}
